﻿using System;
using Bing.Maps;
using GalaSoft.MvvmLight.Messaging;
using Windows.UI.Xaml;
using System.Windows.Input;

namespace Mutzl.Samples.MapApp.MapExtensions
{
    // inspired by http://bindablemaprt.codeplex.com/
    // and http://dreamteam-mobile.com/blog/2012/10/better-bing-maps-sdk-for-metro-apps-winrt-windows8-en/

    public static class MapExtensions
    {
        public static Location GetLocation(DependencyObject obj)
        {
            return (Location)obj.GetValue(LocationProperty);
        }
        public static void SetLocation(DependencyObject obj, Location value)
        {
            obj.SetValue(LocationProperty, value);
        }
        public static readonly DependencyProperty LocationProperty = DependencyProperty.RegisterAttached("Location", typeof(Location), typeof(MapExtensions), new PropertyMetadata(null, OnLocationChanged));
        private static void OnLocationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d != null)
            {
                if ((double)d.GetValue(LatitudeProperty) != double.MinValue || (double)d.GetValue(LongitudeProperty) != double.MinValue)
                    throw new ArgumentException("Define either Location OR Latitude/Longitude!");
                MapLayer.SetPosition(d, (Location)e.NewValue);
            }
        }

        public static double GetLatitude(DependencyObject obj)
        {
            return (double)obj.GetValue(LatitudeProperty);
        }
        public static void SetLatitude(DependencyObject obj, double value)
        {
            obj.SetValue(LatitudeProperty, value);
        }
        public static readonly DependencyProperty LatitudeProperty = DependencyProperty.RegisterAttached("Latitude", typeof(double), typeof(MapExtensions), new PropertyMetadata(double.MinValue, OnLatitudeChanged));
        private static void OnLatitudeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            SetPositon(d);
        }

        
        public static double GetLongitude(DependencyObject obj)
        {
            return (double)obj.GetValue(LongitudeProperty);
        }
        public static void SetLongitude(DependencyObject obj, double value)
        {
            obj.SetValue(LongitudeProperty, value);
        }
        public static readonly DependencyProperty LongitudeProperty = DependencyProperty.RegisterAttached("Longitude", typeof(double), typeof(MapExtensions), new PropertyMetadata(double.MinValue, OnLongitudeChanged));
        private static void OnLongitudeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            SetPositon(d);
        }

        private static void SetPositon(DependencyObject d)
        {
            if (d == null) return;
            
            if (d.GetValue(LocationProperty) != null) throw  new ArgumentException("Define either Latitude/Longitude OR Location!");

            var latitude = (double)d.GetValue(LatitudeProperty);
            var longitude = (double)d.GetValue(LongitudeProperty);

            if (latitude == double.MinValue || longitude == double.MinValue) return;

            MapLayer.SetPosition(d, new Location(latitude, longitude));

        }


        public static Location GetCenter(DependencyObject obj)
        {
            return (Location)obj.GetValue(CenterProperty);
        }
        public static void SetCenter(DependencyObject obj, Location value)
        {
            obj.SetValue(CenterProperty, value);
        }
        public static readonly DependencyProperty CenterProperty = DependencyProperty.RegisterAttached("Center", typeof(Location), typeof(MapExtensions), new PropertyMetadata(null, OnCenterChanged));
        private static void OnCenterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var map = d as Map;
            if (map != null)
            {
                map.Center = (Location)e.NewValue;
            }
        }

        public static Location GetZoom(DependencyObject obj)
        {
            return (Location)obj.GetValue(ZoomProperty);
        }
        public static void SetZoom(DependencyObject obj, Location value)
        {
            obj.SetValue(ZoomProperty, value);
        }
        public static readonly DependencyProperty ZoomProperty = DependencyProperty.RegisterAttached("Zoom", typeof(double), typeof(MapExtensions), new PropertyMetadata(null, OnZoomChanged));
        private static void OnZoomChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var map = d as Map;
            if (map != null)
            {
                map.ZoomLevel = (double)e.NewValue;
            }
        }
    }
}